package com.atguigu.study.controller;

import com.atguigu.study.service.MCPService;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.service.AiServices;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Map;

/**
 * @author Marco
 * @date 2025/8/24 12:40
 * @email 3293336923@qq.com
 * @Description
 *  第1步，如何进行mcp编码
 *   https://docs.langchain4j.dev/tutorials/mcp#creating-an-mcp-tool-provider
 *
 *   第2步，如何使用baidu map mcp，它提供了哪些功能对外服务
 *   https://mcp.so/zh/server/baidu-map/baidu-maps?tab=tools
 *
 *   http://localhost:9014/mcp/chat?question=查询61.149.121.66归属地
 *   http://localhost:9014/mcp/chat?question=查询北京天气
 *   http://localhost:9014/mcp/chat?question=查询昌平到天安门路线规划
 */
@Slf4j
@ConfigurationProperties
@RestController
public class MCPCallServerController {



    @Autowired
    private StreamingChatModel streamingChatModel;
    @GetMapping("/mcp/chat")
    public Flux<String>    chat(@RequestParam("question")   String  question){


//         1.构建McpTransport协议
//         *
//         * 1.1 cmd：启动 Windows 命令行解释器。
//         * 1.2 /c：告诉 cmd 执行完后面的命令后关闭自身。
//         * 1.3 npx：npx = npm execute package，Node.js 的一个工具，用于执行 npm 包中的可执行文件。
//         * 1.4 -y 或 --yes：自动确认操作（类似于默认接受所有提示）。
//         * 1.5 @baidumap/mcp-server-baidu-map：要通过 npx 执行的 npm 包名
//         * 1.6 BAIDU_MAP_API_KEY 是访问百度地图开放平台API的AK

//        百度地图的 api-key
        String   baidu_map_api_key = System.getenv("BAIDU_MAP_API_KEY");
        McpTransport transport = new StdioMcpTransport.Builder()
                .command(List.of( "cmd", "/c", "npx", "-y", "@baidumap/mcp-server-baidu-map"))
                .environment(Map.of("BAIDU_MAP_API_KEY" , baidu_map_api_key))
//                .logEvents(true) // only if you want to see the traffic in the log
                .build();


//         2、构建  MCPClient  客户端
        McpClient mcpClient = new DefaultMcpClient.Builder()
                .transport(transport)
                .build();

//        3、创建 工具集  和 原生的  FunctionCalling 类似
        McpToolProvider toolProvider = McpToolProvider.builder()
                .mcpClients(mcpClient)
                .build();


//        4、通过  AiServices 给我们自定义接口  MCPService 构建实现类并将工具集 和 大模型 赋值给 AiService
        MCPService mcpService = AiServices.builder(MCPService.class)
                .streamingChatModel(streamingChatModel)
                .tools(toolProvider)
                .build();

//        5、调用 我们 定义的  HighApi 接口，通过大模型对百度 mcpserver 进行调用
                return mcpService.chat(question);
    }
}
